package fr.oneview.mapping.csv;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.androwit.engine.MappingReader;
import com.androwit.engine.mapping.MappingField;
import com.androwit.engine.mapping.MappingFieldsDefiner;
import com.csvreader.CsvReader;

/**
 * 
 * Reads a CSV file and keeps the heading information if any: the class presumes there is a header if skipLines greater than zero, the header is always
 * considered to be the 1st line
 * 
 * @author Zied Hamdi - http://1vu.fr
 * 
 */
public class BasicCsvReader implements MappingReader<String, String> {

	protected int skipLines;
	protected String[] headerTitles;
	protected CsvReader reader;
	protected HashMap<String, String> currentLine;

	public BasicCsvReader(String csvFile, char delimiter, int skipLines) throws IOException {
		this.skipLines = skipLines;
		reader = new CsvReader(csvFile, delimiter);
		// only suppose there is a header if skipLines is not 0, the header is considered to be the 1st line
		if (skipLines > 0) {
			reader.readRecord();
			headerTitles = reader.getValues();
		}

		skipLines(reader);
	}

	private void skipLines(CsvReader reader) throws IOException {
		// starts at 1 since the header was read at startup
		for (int i = 1; i < skipLines; i++) {
			reader.readRecord();
		}
	}

	public boolean readRecord() {
		try {
			boolean available = reader.readRecord();
			if (!available)
				close();

			return available;
		} catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void close() {
		reader.close();
	}

	public Map<String, String> getRelevantValues(MappingFieldsDefiner<?, String, String> fieldsDefiner) {
		try {
			return readLine();
		} catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}

	protected Map<String, String> readLine() throws IOException {
		String[] values = reader.getValues();
		currentLine = new HashMap<String, String>();
		for (int i = 0; i < values.length; i++) {
			String key = headerTitles == null ? "" + i : headerTitles[i];
			currentLine.put(key, values[i]);
		}
		return currentLine;
	}

	public String get(MappingField<?, String, String> field) {
		return currentLine.get(field.getKey());
	}

	public String[] getHeaderTitles() {
		return headerTitles;
	}
}
